var gamejs = require('gamejs');

/**
 * Creates a map, which holds a matrix of the navigable terrain and the obstacles
 *@param {Match} match the current match
 *@param {number} width the map width
 *@param {number} height the map height
 */
var Map = exports.Map = function(match, width , height) {
	this.matrix = [];
	this.curPathFinder = new gamejs.worker.Worker('js/pathFinder');
    for (var x=0; x < width; x++) {
    	var nodeRow = [];
    	var gridRow = [];

    	for(var y=0; y < height; y++) {
    		nodeRow.push(GraphNodeType.OPEN);
    	}
    	this.matrix.push(nodeRow);
    }
    this.curPathFinder.post({
		todo: "map",wmatrix: this.matrix
	});
    this.curenemyid = 0;
	this.obstacles = new gamejs.sprite.Group();
	this.enemies = new gamejs.sprite.Group();
	this.turrets = new gamejs.sprite.Group();
	this.radars = new gamejs.sprite.Group();
	this.size= [width,height];
 	this.currentMatch = match;
 	this.background = gamejs.image.load('resources/images/background.png');
 	/*this.original_image_earth = gamejs.image.load('resources/images/earth.png');
 	this.original_image_earth = gamejs.transform.scale(
			this.original_image_earth,
			[height, height]
	);
 	this.earth_rotation = 0;
 	this.image_earth =  gamejs.transform.rotate(this.original_image_earth, this.earth_rotation);
 	*/
}


/**
 * Return the match where this map work.
 *
 * @return {Match} The match where this map work.
 */
Map.prototype.getMatch = function() {
    return this.currentMatch;
}

/**
 * Return the enemies group.
 *
 * @return {Group} The enemies group.
 */
Map.prototype.getEnemies = function() {
	return this.enemies;
}

/**
 * Return the obstacles group.
 *
 * @return {Group} The obstacles group.
 */
Map.prototype.getObstacles = function() {
	return this.obstacles;
}

/**
 * Return the turrets group.
 *
 * @return {Group} The turrets group.
 */
Map.prototype.getTurrets = function() {
	return this.turrets;
}

/**
 * Return the radars group.
 *
 * @return {Group} The radars group.
 */
Map.prototype.getRadars = function() {
	return this.radars;
}

/**
 * Update function
 */
Map.prototype.update = function(){ }

/**
 * Draw on surface
 
 * @param {gamejs.surface} where to draw
 */
Map.prototype.draw = function(surface){
	surface.blit(this.background);
}

/**
 * Get the current map size
 *
 * @returns {Number[]}  The width and height of the Surface
 */
Map.prototype.getSize = function(){
	return this.size;    
}

/** 
 * Fill a pixel
 *
 * @param {array} coordinates The coordinates as vector [x, y]
 */
Map.prototype.fill = function(coordinates) {
	this.matrix[coordinates[0]][coordinates[1]] = false;
};

/**
 * Clear a pixel
 *
 * @param {array} coordinates The coordinates as vector [x, y]
 */
Map.prototype.clear = function(coordinates) {
	this.matrix[coordinates[0]][ coordinates[1]] = true;
};

/**
 * Tells if the pixel is filled
 *
 * @param {array} coordinates The coordinates as vector [x, y]
 *
 * @returns {boolean} True if the pixel is filled, false otherwise
 */
Map.prototype.isFilled = function(coordinates) {
	return  ! this.matrix[coordinates[0]][coordinates[1]];
};

/**
 * Adds an obstacle to the map and fills the sprite area
 *
 * @param {Obstacle} obstacle The obstacle to add
 */
Map.prototype.addObstacle = function(obstacle) {
	this.obstacles.add(obstacle);
	for(var i = 0; i< this.size[0]; i++){
		for(var j=0;j<this.size[1];j++){
			if (Math.sqrt(
					(obstacle.getCenter()[0]- i)*(obstacle.getCenter()[0]- i) +
					(obstacle.getCenter()[1]- j )*(obstacle.getCenter()[1]- j )
					) <= (obstacle.getRadius())
				){
				this.fill([i,j]);
			}
		}
	}
	 this.curPathFinder.post({
			todo: "map",wmatrix: this.matrix
		});
}

/**
 * Removes an obstacle to the map and clears the sprite area
 *
 * @param {Obstacle} obstacle The obstacle to remove
 */
Map.prototype.removeObstacle = function(obstacle) {    //WARNING: controllare il discorso del Path che non capisco bene come funziona
	this.obstacles.remove(obstacle);
	for(var i = 0; i< this.size[0]; i++){
		for(var j=0;j<this.size[1];j++){
			if (Math.sqrt(
					(obstacle.getCenter()[0]- i)*(obstacle.getCenter()[0]- i) +
					(obstacle.getCenter()[1]- j )*(obstacle.getCenter()[1]- j )
					) <= (obstacle.getRadius())
				){
				this.clear([i,j]);
			}
		}
	}
	// this.curPathFinder.post({                              
	//		todo: "map",wmatrix: this.matrix
};


/**
 * Adds an enemy to the map and fills the sprite area
 *
 * @param {Enemy} enemy The enemy to add
 */
Map.prototype.addEnemy = function(enemy) { 
	this.enemies.add(enemy);
}

/**
 * Removes enemy to the map and clears the sprite area
 *
 * @param {Enemy} enemy  They enemy to remove
 */
Map.prototype.removeEnemy = function(enemy) {
	this.enemies.remove(enemy);
}

/**
 * Adds turrett the map and fills the sprite area
 *
 * @param {Turret} turret The turret to add
 */
Map.prototype.addTurret = function(turret) { 
	this.turrets.add(turret);
}

/**
 * Removes an turret from the map and clears the sprite area
 *
 * @param {Turret} turret The turret to remove
 */
Map.prototype.removeTurret = function(turret){ 
	this.turrets.remove(turret);	
}

/**
 * Adds a radar to the map and fills the sprite area
 *
 * @param {Radar} radar The radar to add
 */
Map.prototype.addRadar = function(radar) {
	this.radars.add(radar);
}

/**
 * Removes a radar to the map and clears the sprite area
 *
 * @param {Radar} radar The radar to remove
 */
Map.prototype.removeRadar = function(radar) { }

/**
 * Get a valid path from a point to another point
 *
 * @param {int[2]} startPoint the start point
 * @param {int[2]} endPoint the end point
 */
Map.prototype.getPath = function(id,startPoint,endPoint){
	this.curPathFinder.post({
		todo: "find",wid: id,wstartPoint: startPoint , wendPoint: endPoint
	});
}

/**
 * Draws the radar in the given Surface.
 * 
 * @param {gamejs.Surface} surface The Surface where draw on.
 */
Map.prototype.draw = function(surface) {
	
	surface.blit(this.background, [0, 0]);	
	//surface.blit(this.image_earth, [-400 -(Math.sqrt(2)-1)*Math.abs(Math.cos(this.earth_rotation*Math.PI/45)),-(Math.sqrt(2)-1)*Math.abs(Math.sin(this.earth_rotation*Math.PI/45))]);
}

/**
 * Update the data in the game
 */
Map.prototype.update = function(msDuration){ 
	/*this.image_earth = gamejs.transform.rotate(this.original_image_earth, this.earth_rotation);
	if(this.earth_rotation<360)
		this.earth_rotation+=msDuration/6;
	else
		this.earth_rotation = 0;
		*/
}
/**
 * checks if a pixel is outside the map
 * 
 * @param {array} coordinates The coordinates as vector [x, y]
 */
Map.prototype.isInside = function(point){
	if (point[0]>this.size[0] || point[1]>this.size[1] || point[0]<0 || point[1]<0){
		return false;
	}
	else return true;		
};